﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Windows.Forms;

namespace Home.Haushalt
{
    /// <summary>
    /// 
    /// </summary>
    public class HFile
    {
        /// <summary></summary>
        public string FileStoreFullPath { get; private set; }

        /// <summary></summary>
        public string IconsFullPath { get; private set; }

        /// <summary></summary>
        private string _tempPath;

        /// <summary></summary>
        private string _deletedPath;

        /// <summary></summary>
        private string _autologgingPath;

        /// <summary></summary>
        private HCryptography _cry;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileStorePath"></param>
        /// <param name="cry"></param>
        public HFile(string fileStorePath, HCryptography cry)
        {
            _cry = cry;

            //FileStore-Pfad
            FileStoreFullPath = fileStorePath;
            CreateDirectoryTry(FileStoreFullPath);

            //Temp-Pfad
            _tempPath = Path.Combine(FileStoreFullPath, "Temp");
            CreateDirectoryTry(_tempPath);

            //Delete-Pfad
            _deletedPath = Path.Combine(FileStoreFullPath, "Temp\\Deleted");
            CreateDirectoryTry(_deletedPath);

            //Autologging-Pfad
            _autologgingPath = Path.Combine(FileStoreFullPath, "Autologging");
            CreateDirectoryTry(_autologgingPath);

            //Icons-Path
            IconsFullPath = Path.GetFullPath("Icons");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public bool Delete(string fileName)
        {
            string fullFileName = fileName.IndexOfAny(new char[] { '\\', '/' }).Equals(-1) ? Path.Combine(FileStoreFullPath, fileName) : fileName;

            bool result = !File.Exists(fullFileName);

            if (!result)
            {
                string deletedFileName = Path.Combine(_deletedPath, string.Format("{0}_{1}{2}", Path.GetFileNameWithoutExtension(fileName), Guid.NewGuid(), Path.GetExtension(fileName)));

                try
                {
                    File.Move(fullFileName, deletedFileName);
                    result = !File.Exists(fullFileName) && File.Exists(deletedFileName);
                }
                catch (Exception ex)
                {
                    result = false;

                    Journal.Add(this, ex);
                }

                if (!result)
                {
                    Journal.Add(this, ActionResult.Nok, string.Format("Datei konnte nicht gelöscht werden: Produktive Datei existiert={0}; gelöschte Datei existiert={1}", File.Exists(fullFileName) && File.Exists(deletedFileName)));
                }
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        public void ClearTemp()
        {
            foreach (string tempFileName in Directory.GetFiles(_tempPath, "*.*", SearchOption.TopDirectoryOnly))
            {
                try
                {
                    File.Delete(tempFileName);
                }
                catch (Exception ex)
                {
                    Journal.Add(this, ex);
                }
            }
        }

        /// <summary>
        /// Kopiert aus Zwieschenanlage ins Temp
        /// </summary>
        /// <returns></returns>
        public string CreateImageFromClipboard()
        {
            string filename = Path.Combine(_tempPath, "img_from_clipboard_" + Guid.NewGuid() + ".png");
            try
            {
                Clipboard.GetImage().Save(filename);
            }
            catch { }

            return filename;
        }

        /// <summary>
        /// Decripted Kopie einer Datei
        /// </summary>
        /// <param name="fullFileName"></param>
        /// <returns>Pfad zur decripteten Datei</returns>
        public string GetDecryptedFileTry(string fullFileName)
        {
            string tempFileName = Path.Combine(_tempPath, Path.GetFileName(fullFileName));

            if (!File.Exists(tempFileName))
            {
                //In Temp kopieren
                try
                {
                    File.Copy(fullFileName, tempFileName, true);
                }
                catch (Exception ex)
                {
                    Journal.Add(this, "Datei [" + fullFileName + "] in Temp [" + tempFileName + "] kopieren", ex);
                    return fullFileName;
                }

                //Decrypten
                try
                {
                    _cry.FileDecrypt(tempFileName);
                }
                catch (Exception ex)
                {
                    Journal.Add(this, "Datei [" + tempFileName + "] decrypten", ex);
                    return fullFileName;
                }
            }

            return tempFileName;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="directoryName"></param>
        /// <returns></returns>
        private bool CreateDirectoryTry(string directoryName)
        {
            bool result = Directory.Exists(directoryName);

            if (!result)
            {
                try
                {
                    Directory.CreateDirectory(directoryName);

                    result = Directory.Exists(directoryName);
                }
                catch (Exception ex)
                {
                    result = false;

                    Journal.Add(this, ex);
                }
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iconFileName"></param>
        /// <returns></returns>
        public string ProvideIcon(string iconFileName)
        {
            try
            {
                if (!iconFileName.Equals(string.Empty))
                {
                    string sourcePath = Path.GetDirectoryName(iconFileName);

                    if (sourcePath.Equals(string.Empty))
                    {
                        iconFileName = Path.Combine(IconsFullPath, iconFileName);
                        sourcePath = Path.GetDirectoryName(iconFileName);
                    }

                    if (!File.Exists(iconFileName))
                        return "";

                    if (sourcePath.Equals(IconsFullPath))
                    {
                        iconFileName = Path.GetFileName(iconFileName);
                    }
                    else
                    {
                        string targetFileName = Path.Combine(IconsFullPath, Path.GetFileName(iconFileName));

                        int copyIndex = 1;
                        while (File.Exists(targetFileName))
                            targetFileName = Path.Combine(IconsFullPath, string.Format("{0}_#{1}{2}", Path.GetFileNameWithoutExtension(iconFileName), copyIndex++, Path.GetExtension(iconFileName)));

                        File.Copy(iconFileName, targetFileName);

                        iconFileName = Path.GetFileName(targetFileName); ;
                    }
                }
            }
            catch
            {
                iconFileName = "";
            }

            return iconFileName;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sourcePath"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string GetFileContent(string fullFileName)
        {
            using (StreamReader sr = new StreamReader(fullFileName))
            {
                string fileContent = sr.ReadToEnd();
                sr.Close();
                return fileContent;
            }
        }

        #region AUTOLOGIN
        /// <summary>
        /// 
        /// </summary>
        /// <param name="memberID"></param>
        /// <returns></returns>
        public bool AutoLoginExists(int memberID)
        {
            string filePath = Path.Combine(_autologgingPath, memberID.ToString() + ".cry");
            return File.Exists(filePath);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="memberID"></param>
        /// <returns></returns>
        public bool DeleteAutoLoginFile(int memberID)
        {
            return Chips.FileTryDelete(Path.Combine(_autologgingPath, memberID.ToString() + ".cry"));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="memberID"></param>
        /// <returns></returns>
        public string DecriptAutoLoginFile(int memberID)
        {
            string targetFilePath = Path.Combine(_autologgingPath, memberID.ToString() + ".htm");

            StreamReader sr = new StreamReader(Path.Combine(_autologgingPath, memberID.ToString() + ".cry"));
            string encryptContnet = sr.ReadToEnd();
            sr.Close();

            StreamWriter sw = new StreamWriter(targetFilePath, false);
            sw.Write(_cry.Decrypt64(encryptContnet));
            sw.Close();

            return targetFilePath;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="memberID"></param>
        /// <param name="autologinBody"></param>
        public void CreateAutoLoginFile(int memberID, string autologinBody)
        {
            StreamWriter sw = new StreamWriter(Path.Combine(_autologgingPath, memberID.ToString() + ".cry"), false);
            try
            {
                sw.Write(_cry.Encrypt64(autologinBody));
                sw.Close();
            }
            catch (Exception ex)
            {
                Journal.Add(this, ex);
                //MessageBox.Show("Aktion gescheitert: " + ex.Message);
                if (sw != null) sw.Close();
            }

        }
        #endregion autologin


    }
}
